/**
  ******************************************************************************
  * @文件名           : dri_slaver_smc_rtu.c
  * @作者             : citunhk
  * @功能介绍         : SMC_RTU从机驱动
  *	@日期             : 2024.3.21
  ******************************************************************************
  * @注意
  *
  * 本文件中不应调用上层文件
  *
  ******************************************************************************
  *更改记录
  *日期 修改人 修改内容
  *
  *
  *
  ******************************************************************************
  */
#include "dri_slaver_smc_rtu.h"
#include "dri_slaver.h"
#include "bsp_usart.h"
#include "fml_crc.h"
#include "sys_data.h"
#include "dri_flash_sst.h"

/**
* @函数名	DRI_SMC_RTU_TxRegSlaverValue
* @功能	    将03指令需要的数据填充到相应的寄存器中
* @入口参数	无
* @返回值	无
*/
void DRI_SMC_RTU_TxRegSlaverValue(unsigned int uiRegIndex)
{
	uint16_t pModbusSlaverUpData = 0;
	switch(uiRegIndex)
	{
		case 0x30:
			pModbusSlaverUpData=((int16_t)(10*gPV_Temp1));//主温度实测值
			break;
		case 0x34:
			pModbusSlaverUpData=((int16_t)(gPV_Press_Out));//出液压力实测值
			break;
		case 0x36:
			pModbusSlaverUpData=((int16_t)(10*gPV_Flow));//流量实测值
			break;
		case 0x38:
			pModbusSlaverUpData=((int16_t)(10*gSlaver_DisplayData1));//数据显示1
			break;
		case 0x39:
			pModbusSlaverUpData=((int16_t)(10*gSlaver_DisplayData2));//数据显示2
			break;
		case 0x3A:
			pModbusSlaverUpData=((int16_t)(10*gSlaver_DisplayData3));//数据显示3
			break;
		case 0x3B:
			pModbusSlaverUpData=((int16_t)(10*gSlaver_DisplayData4));//数据显示4
			break;
		case 0x3C:
			pModbusSlaverUpData=rSlaver_State_Chiller;//设备状态组
			break;
		case 0x3D:
			pModbusSlaverUpData=rSlaver_State_Alarm1;//报警状态组1
			break;
		case 0x3E:
			pModbusSlaverUpData=rSlaver_State_Alarm2;//报警状态组2
			break;
		case 0x3F:
			pModbusSlaverUpData=rSlaver_State_Alarm3;//报警状态组3
			break;
		case 0x40:
			pModbusSlaverUpData=((int16_t)(10*UP.Para.SV_Temp1));//主温度设定值
			break;
		case 0x42:
			pModbusSlaverUpData=rSlaver_Operation;//操作指令
			break;
		case 0x43:
			pModbusSlaverUpData=UP.Para.rSlaver_Data;//数据指令
			break;
		default:
//			gSlaver_State = 50;
		break;
	}

	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=(uint8_t)(pModbusSlaverUpData>>8);
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=(uint8_t)(pModbusSlaverUpData&0x00ff);
}

/**
* @函数名	DRI_SMC_RTU_ProcessModbusSlaverUpCmd03
* @功能	    03指令解析处理
* @入口参数	无
* @返回值	无
*/
void DRI_SMC_RTU_ProcessModbusSlaverUpCmd03(void)
{
	uint16_t uiStart;
	uint16_t uiQuantity;
	uint16_t uiEnd;
	uint16_t i;

	//字节个数
	uiQuantity=((uint16_t)gBus485_Slaver_RxBuffer[4]<<8)+gBus485_Slaver_RxBuffer[5];
	if(uiQuantity>0x7D)
	{
		//ExceptionResponse(0x03);
		return;
	}
	//起始地址
	uiStart=((uint16_t)gBus485_Slaver_RxBuffer[2]<<8)+gBus485_Slaver_RxBuffer[3];
	//结束地址
	uiEnd=uiStart+uiQuantity;
//		if(ModbusUpListenOnly)
//		{
//			ModbusUpUartInit();
//			return;
//		}
	pBus485_Slaver_TxCounter=0;
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[0];
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[1];
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=uiQuantity*2;
	for(i=uiStart;i<uiEnd;i++)
	{
		DRI_SMC_RTU_TxRegSlaverValue(i);
	}
	DRI_MakeModbusSlaverUpMsgCrc();
	DRI_SlaverUpStartTx();
}

/**
* @函数名	DRI_SMC_RTU_ProcessModbusSlaverUpCmd06
* @功能	    06指令解析处理
* @入口参数	无
* @返回值	无
*/
//写单个寄存器指令
void DRI_SMC_RTU_ProcessModbusSlaverUpCmd06()
{
	uint16_t uiStart;
	uint16_t uiQuantity=0;
	uint8_t pFlag_Save = 1;  //保存标志位

	if(uiQuantity>0x7D)
	{
		//ExceptionResponse(0x03);
		return;
	}
	uiStart=((uint16_t)gBus485_Slaver_RxBuffer[2]<<8)+gBus485_Slaver_RxBuffer[3];
//	if(ModbusUpListenOnly)
//	{
//		ModbusUpUartInit();
//		return;
//	}
	pBus485_Slaver_TxCounter=0;
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[0];
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[1];

	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[2];
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[3];

	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[4];
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[5];
	DRI_MakeModbusSlaverUpMsgCrc();
	DRI_SlaverUpStartTx();

	if(uiStart >= 0)
	{
		switch(uiStart)
		{
		case 0x40:
			UP.Para.SV_Temp1=((float)(int16_t)((gBus485_Slaver_RxBuffer[4]<<8) + gBus485_Slaver_RxBuffer[5]))/10;//主温度设定
			break;
		case 0x42:
			rSlaver_Operation=(gBus485_Slaver_RxBuffer[4]<<8) + gBus485_Slaver_RxBuffer[5];//操作指令
			pFlag_Save = 0;
			break;
		case 0x43:
			UP.Para.rSlaver_Data=(gBus485_Slaver_RxBuffer[4]<<8) + gBus485_Slaver_RxBuffer[5];//数据指令
			break;
			default:
//				gSlaver_State = 50;
				break;
		}

		if(pFlag_Save == 1)
		{
			DRI_Flash_Erase_4KByte(ADDR_USER_PARA);//写入前擦除
			DRI_Flash_AAI_WriteBuffer(&UP.flashBuff[0], ADDR_USER_PARA, 500);//写入用户初值到buff中
		}
	}
}

/**
* @函数名	DRI_SMC_RTU_ProcessModbusSlaverUpCmd16
* @功能	    16指令解析处理
* @入口参数	无
* @返回值	无
*/
//写多个寄存器指令  16指令
void DRI_SMC_RTU_ProcessModbusSlaverUpCmd16()
{
	uint16_t uiStart;
	uint16_t uiEnd;
	uint16_t uiQuantity;
	uint16_t i;
	uint16_t FlagCmdModbus = 0;
	uint8_t pFlag_Save = 1;  //保存标志位

	//寄存器个数
	uiQuantity=((uint16_t)gBus485_Slaver_RxBuffer[4]<<8)+gBus485_Slaver_RxBuffer[5];
	if(uiQuantity>0x7D)
	{
		//ExceptionResponse(0x03);
		return;
	}
	//寄存器起始地址
	uiStart=((uint16_t)gBus485_Slaver_RxBuffer[2]<<8)+gBus485_Slaver_RxBuffer[3];
	//结束地址
	uiEnd=uiStart+uiQuantity;
	for(i=uiStart;i<uiEnd;i++)
	{
		 switch(i)
		 {
			case 0x40:  //主温度设定值
				UP.Para.SV_Temp1 = ((float)(int16_t)((gBus485_Slaver_RxBuffer[7]<<8) + gBus485_Slaver_RxBuffer[8]))/10;
				FlagCmdModbus = FlagCmdModbus + 2;
				break;
			case 0x41:  //预留
				FlagCmdModbus = FlagCmdModbus + 2;
				break;
			case 0x42:  //操作指令
				rSlaver_Operation = ((uint16_t)(gBus485_Slaver_RxBuffer[7+FlagCmdModbus]<<8) + gBus485_Slaver_RxBuffer[8+FlagCmdModbus]);
				FlagCmdModbus = FlagCmdModbus + 2;
				pFlag_Save = 0;
				break;
			default:
//				gSlaver_State = 50;
				break;
		}
	}

//    if(FlagCmdModbus==1)
//    {
    	FlagCmdModbus = 0;
		pBus485_Slaver_TxCounter = 0;
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[0];
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[1];
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[2];
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[3];
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[4];
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[5];
		DRI_MakeModbusSlaverUpMsgCrc();
		DRI_SlaverUpStartTx();
//    }

		if(pFlag_Save == 1)
		{
			DRI_Flash_Erase_4KByte(ADDR_USER_PARA);//写入前擦除
			DRI_Flash_AAI_WriteBuffer(&UP.flashBuff[0], ADDR_USER_PARA, 500);//写入用户初值到buff中
		}
}

/**
* @函数名	DRI_SMC_RTU_Slaver_RX_Integration
* @功能	    SMC_RTU的RS485从机数据处理
* @入口参数	无
* @返回值	无
*/
void DRI_SMC_RTU_Slaver_RX_Integration(void)
{
	uint16_t puiCRCResult;
	uint8_t pModbusUpFrameSlaverStatus=1;
	if(gBus485_Slaver_RxCounter<3) //如果数据字节少于3
	{
		pModbusUpFrameSlaverStatus=1;
	}
	else
	{
		uint16_t crcdata;
//		Crc16Arg.pCrc16ArgsPuchMsg=gBus485_Slaver_RxBuffer;  //获取等待CRC数组地址
//		Crc16Arg.crc16ArgsPuchMsgLen=gBus485_Slaver_RxCounter-2;  //获取等待CRC数组长度  不包含原CRC
		puiCRCResult = Crc16(gBus485_Slaver_RxBuffer, gBus485_Slaver_RxCounter-2);
//		puiCRCResult=Crc16Arg.returnValue;  //得到CRC数值
		crcdata = (gBus485_Slaver_RxBuffer[gBus485_Slaver_RxCounter-1]<<8)|(gBus485_Slaver_RxBuffer[gBus485_Slaver_RxCounter-2]);
		gBus485_Slaver_RxCounter = 0;  //清除计数标志
		if((crcdata - puiCRCResult) == 0)//CRC校验通过
		{
			if((gBus485_Slaver_RxBuffer[0]==UP.Para.RS485_Addr)||(gBus485_Slaver_RxBuffer[0]==0))
			{
				pModbusUpFrameSlaverStatus=0;  //接收成功
			}
		}
		else
		{
				pModbusUpFrameSlaverStatus=1;//接收失败
		}
	}
	if(pModbusUpFrameSlaverStatus==0)
	{
		if(gBus485_Slaver_RxBuffer[0])  //地址不为0
		{
			switch(gBus485_Slaver_RxBuffer[1])  //判断指令
			{
				case 3://读多个寄存器
					gSlaver_State = 0;
					DRI_SMC_RTU_ProcessModbusSlaverUpCmd03();
					break;
				case 6://写单个寄存器
					gSlaver_State = 0;
					DRI_SMC_RTU_ProcessModbusSlaverUpCmd06();
					break;
				case 16://写多个寄存器
					gSlaver_State = 0;
					DRI_SMC_RTU_ProcessModbusSlaverUpCmd16();
					break;
				default:
				break;
			}
		}
	}
}











